'''
Created on Apr 26, 2011

@author: Igor
'''
from lib.common_cards import has_straight, get_top_combo, Combo, get_kickers,\
        get_two_card_combos, get_combos_with_indicators, \
        cmp_combos, print_two_card_combos,\
        print_five_card_combos, cmp_hand

import unittest

class Test(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_has_straight(self):
        assert has_straight([15, 14, 16, 17, 18]) == 5
        assert has_straight([14, 15, 16, 17, 19]) is None
        assert has_straight([4, 18, 6, 8, 7]) == 8
        assert has_straight([4, 5, 9, 7, 8, 6, 10]) == 10
        assert has_straight([10, 9, 5, 7, 6, 8, 4]) == 10
        assert has_straight([14, 15, 16, 17]) is None
        assert has_straight([25, 13, 16, 15, 14]) == 3
        
    def test_get_top_combo(self):
        assert get_top_combo([35, 38, 36, 37, 34]) == \
                Combo.ROYAL_STRAIGHT_FLUSH
        assert get_top_combo([15, 14, 16, 17, 18]) == Combo.STRAIGHT_FLUSH
        assert get_top_combo([15, 2, 28, 17, 41]) == Combo.FOUR_OF_A_KIND
        assert get_top_combo([29, 4, 16, 17, 43]) == Combo.FULL_HOUSE
        assert get_top_combo([15, 13, 16, 17, 18]) == Combo.FLUSH
        assert get_top_combo([12, 24, 36, 48, 47]) == Combo.STRAIGHT
        assert get_top_combo([0, 13, 16, 26, 18]) == Combo.THREE_OF_A_KIND
        assert get_top_combo([15, 3, 16, 17, 28]) == Combo.TWO_PAIRS
        assert get_top_combo([9, 13, 16, 35, 18]) == Combo.PAIR_JACKS
        assert get_top_combo([15, 3, 16, 17, 18]) == Combo.PAIR
        assert get_top_combo([15, 13, 38, 17, 18]) == Combo.SINGLE
        
    def test_get_kickers(self):
        assert get_kickers([13, 16, 34, 5, 7], 1, [7]) == \
                [[Combo.SINGLE, [8]]]
        assert get_kickers([13, 12, 34, 38, 7, 50], 3, [12]) == \
                [[Combo.SINGLE, [11]], [Combo.SINGLE, [8]],
                 [Combo.SINGLE, [7]]]
        assert get_kickers([13, 12, 34, 38, 7], 2, [12, 8]) == \
                [[Combo.SINGLE, [7]], [Combo.SINGLE, [0]]]
        assert get_kickers([13, 12, 34, 38, 7], 1, [12, 8, 7]) == \
                [[Combo.SINGLE, [0]]]
    
    def test_get_two_card_combos(self):
        assert get_two_card_combos([14, 17]) == [[Combo.SINGLE, [4]],
                                                 [Combo.SINGLE, [1]]]
        assert get_two_card_combos([24, 50]) == [[Combo.PAIR, [11]]]
        assert get_two_card_combos([30, 14]) == [[Combo.SINGLE, [4]],
                                                 [Combo.SINGLE, [1]]]
        assert get_two_card_combos([25, 51]) == [[Combo.PAIR, [12]]]
        
    def test_get_combos_with_indicators(self):
        assert get_combos_with_indicators([31, 32, 33, 35, 34, 44, 3]) == \
                [[Combo.STRAIGHT_FLUSH, [9]]]
        assert get_combos_with_indicators([29, 45, 16, 9, 42, 44, 3]) == \
                [[Combo.FOUR_OF_A_KIND, [3]], [Combo.SINGLE, [9]]]
        assert get_combos_with_indicators([29, 45, 16, 9, 19, 44, 3]) == \
                [[Combo.FULL_HOUSE, [3, 6]]]
        assert get_combos_with_indicators([22, 15, 16, 18, 19, 14, 23]) == \
                [[Combo.FLUSH, [10, 9, 6, 5, 3]]]
        assert get_combos_with_indicators([5, 45, 20, 9, 34, 44, 3]) == \
                [[Combo.STRAIGHT, [9]]]
        assert get_combos_with_indicators([5, 44, 20, 18, 34, 24, 3]) == \
                [[Combo.THREE_OF_A_KIND, [5]], [Combo.SINGLE, [11]], 
                 [Combo.SINGLE, [8]]]
        assert get_combos_with_indicators([11, 44, 20, 18, 34, 24, 3]) == \
                [[Combo.TWO_PAIRS, [11, 5]], [Combo.SINGLE, [8]]]
        assert get_combos_with_indicators([15, 44, 20, 18, 34, 24, 3]) == \
                [[Combo.PAIR, [5]], [Combo.SINGLE, [11]], [Combo.SINGLE, [8]],
                 [Combo.SINGLE, [7]]]
        assert get_combos_with_indicators([15, 0, 20, 18, 34, 24, 3]) == \
                [[Combo.SINGLE, [11]], [Combo.SINGLE, [8]],
                 [Combo.SINGLE, [7]], [Combo.SINGLE, [5]],
                 [Combo.SINGLE, [3]]]

    def test_cmp_combos(self):
        assert cmp_combos([[Combo.FULL_HOUSE, [3, 6]]],
                [[Combo.STRAIGHT, [9]]]) > 0
        assert cmp_combos([[Combo.STRAIGHT, [6]]],
                [[Combo.STRAIGHT, [9]]]) < 0
        assert cmp_combos([[Combo.FLUSH, 
                [9, 5, 4, 3, 0]]], [[Combo.FLUSH, [9, 5, 4, 2, 1]]]) > 0
        assert cmp_combos([[Combo.TWO_PAIRS, [9, 3]],
                [Combo.SINGLE, [6]]], [[Combo.TWO_PAIRS, [8, 7]],
                [Combo.SINGLE, [12]]]) > 0
        assert cmp_combos([[Combo.PAIR, [9]],
                [Combo.SINGLE, [12]], [Combo.SINGLE, [11]],
                [Combo.SINGLE, [6]]], [[Combo.PAIR, [9]],
                [Combo.SINGLE, [12]], [Combo.SINGLE, [11]],
                [Combo.SINGLE, [4]]]) > 0
        assert cmp_combos([[Combo.PAIR, [6]], 
                [Combo.SINGLE, [12]], [Combo.SINGLE, [10]],
                [Combo.SINGLE, [4]]], [[Combo.PAIR, [6]],
                [Combo.SINGLE, [12]], [Combo.SINGLE, [10]],
                [Combo.SINGLE, [4]]]) == 0
    
    def test_cmp_hand(self):
        # Two cards
        my_hand = get_combos_with_indicators([11, 7])
        assert cmp_hand(my_hand, [6, 6]) < 0
        assert cmp_hand(my_hand, [12, 6]) < 0
        assert cmp_hand(my_hand, [11, 10]) < 0
        assert cmp_hand(my_hand, [11, 7]) == 0
        assert cmp_hand(my_hand, [11, 6]) > 0
        assert cmp_hand(my_hand, [10, 9]) > 0
        # Five cards
        # Straight flush
        my_hand = get_combos_with_indicators([17, 18, 19, 20, 21])
        assert cmp_hand(my_hand, [22, 21, 20, 19, 18]) < 0
        assert cmp_hand(my_hand, [21, 20, 19, 18, 17]) == 0
        assert cmp_hand(my_hand, [16, 17, 18, 19, 20]) > 0
        assert cmp_hand(my_hand, [11, 24, 37, 50, 7]) > 0
        assert cmp_hand(my_hand, [22, 21, 20, 19, 17]) > 0
        # Four of a kind
        my_hand = get_combos_with_indicators([6, 19, 32, 45, 21])
        assert cmp_hand(my_hand, [22, 21, 20, 19, 18]) < 0
        assert cmp_hand(my_hand, [7, 20, 33, 46, 0]) < 0
        assert cmp_hand(my_hand, [45, 32, 19, 6, 23]) < 0
        assert cmp_hand(my_hand, [21, 6, 19, 32, 45]) == 0
        assert cmp_hand(my_hand, [6, 19, 20, 32, 45]) > 0
        assert cmp_hand(my_hand, [6, 19, 20, 32, 46]) > 0
        # Full house
        my_hand = get_combos_with_indicators([6, 19, 32, 15, 2])
        assert cmp_hand(my_hand, [22, 21, 20, 19, 18]) < 0
        assert cmp_hand(my_hand, [0, 6, 19, 32, 45]) < 0
        assert cmp_hand(my_hand, [7, 20, 33, 0, 13]) < 0
        assert cmp_hand(my_hand, [6, 19, 32, 16, 3]) < 0
        assert cmp_hand(my_hand, [6, 19, 32, 2, 15]) == 0
        assert cmp_hand(my_hand, [6, 19, 32, 14, 1]) > 0
        assert cmp_hand(my_hand, [11, 24, 37, 16, 8]) > 0
        # Flush
        my_hand = get_combos_with_indicators([6, 9, 10, 3, 2])
        assert cmp_hand(my_hand, [7, 8, 9, 6, 5]) < 0
        assert cmp_hand(my_hand, [6, 19, 32, 16, 3]) < 0
        assert cmp_hand(my_hand, [6, 11, 0, 1, 3]) < 0
        assert cmp_hand(my_hand, [6, 10, 3, 2, 9]) == 0
        assert cmp_hand(my_hand, [6, 9, 10, 3, 1]) > 0
        assert cmp_hand(my_hand, [7, 8, 9, 4, 5]) > 0
        # Straight
        my_hand = get_combos_with_indicators([6, 5, 17, 3, 2])
        assert cmp_hand(my_hand, [12, 1, 2, 4, 3]) < 0
        assert cmp_hand(my_hand, [6, 1, 2, 4, 3]) < 0
        assert cmp_hand(my_hand, [7, 5, 6, 4, 3]) < 0
        assert cmp_hand(my_hand, [6, 5, 4, 2, 16]) == 0
        assert cmp_hand(my_hand, [12, 1, 2, 3, 17]) > 0
        assert cmp_hand(my_hand, [7, 8, 20, 4, 5]) > 0
        # Three of a kind
        my_hand = get_combos_with_indicators([6, 19, 32, 9, 2])
        assert cmp_hand(my_hand, [18, 1, 2, 4, 3]) < 0
        assert cmp_hand(my_hand, [11, 24, 37, 1, 0]) < 0
        assert cmp_hand(my_hand, [6, 19, 32, 10, 0]) < 0
        assert cmp_hand(my_hand, [6, 19, 32, 2, 9]) == 0
        assert cmp_hand(my_hand, [6, 19, 32, 8, 7]) > 0
        assert cmp_hand(my_hand, [5, 18, 31, 12, 11]) > 0
        assert cmp_hand(my_hand, [14, 1, 2, 25, 12]) > 0
        # Two pairs
        my_hand = get_combos_with_indicators([6, 19, 22, 9, 2])
        assert cmp_hand(my_hand, [6, 19, 32, 10, 0]) < 0
        assert cmp_hand(my_hand, [4, 17, 23, 10, 0]) < 0
        assert cmp_hand(my_hand, [6, 19, 22, 3, 9]) < 0
        assert cmp_hand(my_hand, [6, 19, 22, 2, 9]) == 0
        assert cmp_hand(my_hand, [6, 19, 22, 1, 9]) > 0
        assert cmp_hand(my_hand, [7, 20, 21, 8, 5]) > 0
        assert cmp_hand(my_hand, [14, 1, 2, 15, 12]) > 0
        assert cmp_hand(my_hand, [9, 10, 25, 12, 11]) > 0
        # Pair
        my_hand = get_combos_with_indicators([6, 19, 9, 8, 2])
        assert cmp_hand(my_hand, [6, 14, 1, 13, 0]) < 0
        assert cmp_hand(my_hand, [7, 20, 2, 1, 0]) < 0
        assert cmp_hand(my_hand, [6, 19, 7, 3, 10]) < 0
        assert cmp_hand(my_hand, [6, 19, 8, 2, 9]) == 0
        assert cmp_hand(my_hand, [6, 19, 8, 1, 9]) > 0
        assert cmp_hand(my_hand, [6, 19, 7, 3, 9]) > 0
        assert cmp_hand(my_hand, [12, 11, 10, 9, 20]) > 0
        # Single
        my_hand = get_combos_with_indicators([6, 20, 9, 8, 2])
        assert cmp_hand(my_hand, [6, 4, 1, 13, 0]) < 0
        assert cmp_hand(my_hand, [10, 16, 2, 1, 0]) < 0
        assert cmp_hand(my_hand, [6, 20, 9, 8, 4]) < 0
        assert cmp_hand(my_hand, [6, 20, 8, 2, 9]) == 0
        assert cmp_hand(my_hand, [6, 20, 5, 3, 9]) > 0

    def test_print_two_card_combos(self):
        assert "8 8" == print_two_card_combos([[Combo.PAIR, [6]]])
        assert "6 6" == print_two_card_combos([[Combo.PAIR, [4]]])
        assert "8 5" == print_two_card_combos([[Combo.SINGLE, [6]],
                                               [Combo.SINGLE, [3]]])
        
    def test_print_five_card_combos(self):
        assert "5 5 5 8 8" == print_five_card_combos([[Combo.FULL_HOUSE,
                                                       [3, 6]]])
        assert "Straight to J" == print_five_card_combos([[Combo.STRAIGHT,
                                                           [9]]])
        assert "Flush (J, 7, 6, 5, 2)" == print_five_card_combos([
                [Combo.FLUSH, [9, 5, 4, 3, 0]]])
        assert "J J 5 5 8" == print_five_card_combos([[Combo.TWO_PAIRS,
                [9, 3]], [Combo.SINGLE, [6]]])
        assert "J J A K 8" == print_five_card_combos([[Combo.PAIR, [9]],
                [Combo.SINGLE, [12]], [Combo.SINGLE, [11]], [Combo.SINGLE,
                [6]]])
        assert "A K Q 8 6" == print_five_card_combos([[Combo.SINGLE, [12]],
                [Combo.SINGLE, [11]], [Combo.SINGLE, [10]],
                [Combo.SINGLE, [6]], [Combo.SINGLE, [4]]])

if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testRankName']
    unittest.main()